package app.server.project.main.service.service.race;

import app.server.project.core.exception.SysError;
import app.server.project.core.http.CMSLstResp;
import app.server.project.core.util.AssertUtil;
import app.server.project.main.service.bo.event.AddRaceValEvent;
import app.server.project.main.service.bo.event.RaceCfgEvent;
import app.server.project.main.service.db.dao.cfg.RaceCfgDao;
import app.server.project.main.service.db.entity.cfg.RaceCfgEntity;
import app.server.project.main.service.dto.cms.CoinDto;
import app.server.project.main.service.dto.cms.RaceCfgDto;
import app.server.project.main.service.service.ResService;
import app.server.project.main.service.service.cms.GMService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.EnumUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.Objects;

@RequiredArgsConstructor
@Service
@Slf4j
public class RaceCfgService {


    private final RaceCfgDao raceCfgDao;
    private final ApplicationEventPublisher applicationEventPublisher;
    private final GMService gmService;
    private final ResService resService;


    public CMSLstResp<RaceCfgEntity> getAll() {
        return CMSLstResp.of(this.raceCfgDao.getAll(), this.raceCfgDao.getAll().size());
    }

    public void chk(RaceCfgDto raceCfgDto) {
        //检查一下开始时间
        if (Objects.nonNull(raceCfgDto.getStartTime()) && Objects.nonNull(raceCfgDto.getEndTime())) {
            var startTime = LocalDateTime.parse(raceCfgDto.getStartTime());
            var endTime = LocalDateTime.parse(raceCfgDto.getEndTime());
            AssertUtil.isTrue(endTime.isAfter(startTime), SysError.Activity_Time);
        }
    }

    public void add(RaceCfgDto dto) {
        RaceCfgEntity cfg = new RaceCfgEntity();
        this.chk(dto);
        BeanUtil.copyProperties(dto, cfg, true);
        this.raceCfgDao.save(cfg);
        this.raceCfgDao.init();

    }

    public void edit(RaceCfgDto dto) {
        RaceCfgEntity cfg = new RaceCfgEntity();
        this.chk(dto);
        BeanUtil.copyProperties(dto, cfg, true);
        this.raceCfgDao.saveOrUpdate(cfg);
        this.raceCfgDao.init();
        this.applicationEventPublisher.publishEvent(RaceCfgEvent.of());
    }

    public void del(RaceCfgDto raceCfgEntity) {
        this.raceCfgDao.del(raceCfgEntity.getId());
        this.raceCfgDao.init();
    }

    public void uploadLogo(MultipartFile files, int raceId) {
        var imgUrl = this.gmService.uploadSingleImg(files);
        var raceCfg = this.raceCfgDao.getOne(raceId);
        raceCfg.setLogoUrl(imgUrl);
        this.raceCfgDao.saveOrUpdate(raceCfg);
        this.raceCfgDao.init();
    }

    public void uploadNama(MultipartFile files, int raceId) {
        var imgUrl = this.gmService.uploadSingleImg(files);
        var raceCfg = this.raceCfgDao.getOne(raceId);
        raceCfg.setRaceNameUrl(imgUrl);
        this.raceCfgDao.saveOrUpdate(raceCfg);
        this.raceCfgDao.init();
    }

    public void addCoin(CoinDto addCoinReq) {
        var detailType = EnumUtil.getBy(DetailType.class, v -> v.getType() == addCoinReq.getDetailType());
        if (Objects.isNull(detailType)) {
            return;
        }
        this.resService.addResNum(Long.parseLong(addCoinReq.getUserId()), addCoinReq.getRaceId(), addCoinReq.getAddNum(), true);
        var cfg = this.raceCfgDao.getOne(addCoinReq.getRaceId());
        this.applicationEventPublisher.publishEvent(AddRaceValEvent.of(Long.parseLong(addCoinReq.getUserId()), cfg, addCoinReq.getAddNum(), DetailType.Rank.getType()));
    }

    public void consumeCoin(CoinDto addCoinReq) {

        this.resService.consumeRaceNum(Long.parseLong(addCoinReq.getUserId()), addCoinReq.getAddNum(), addCoinReq.getRaceId());

    }
}
